home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-11-18 | 6.7 KB | 128 lines | [TEXT/MPS ] |
- Macintosh
- Sample Code Notes
- _______________________________________________________________________________
- Developer Technical Support
-
- #xx: INIT - CDEV
-
- Written by: Keith Rollin
-
- Versions: 1.00 February 1991
-
- Components: CDEV.c C source
- CDEV.rsrc Misc resources
- Common.h C header for CDEV.c & INIT.c
- INIT - CDEV.make Makefile
- INIT.a Asm source
- INIT.c C source
- INITInstall.a Asm source
- SAGlobals.c C source
- SAGlobals.h C header
- SCN.xxx.INIT - CDEV About file
- ShowINIT.a.o ShowINIT library file (supplied as
- object file only, so don't
- delete it).
-
- _______________________________________________________________________________
-
- “INIT - CDEV” is a sample that shows how a CDEV can communicate with an INIT.
- It is a System 7.0 sample, as it uses the PPCToolbox. It also uses the
- FindFolder routine to show how to read and write a preferences file, and the
- stand-alone globals techniques described in Technote #256.
-
- This sample demonstrates the following:
-
- • How to write an INIT that can stay resident.
- • How to write a Control Panel Device with extended error reporting
- • How to patch a trap
- • How to use the FindFolder routine for managing preferences
- • How to do quick and dirty PPCToolbox communications
- • How to use global variables in standalone code
-
-
- The INIT is just a simple "do nothing" INIT. It patches into SystemTask so
- that it can beep a certain number of times at regular intervals. At startup
- time, it reads a preferences file to find out how many times it should beep,
- and how often. If there isn't a preferences file, or we are running under
- 6.0.x and don't have the luxery of the FindFolder routine, we use the
- hard-wired setting of beeping 3 times every minute. However, the INIT doesn't
- really do anything 7.0-ish, so it still installs at startup even if you are
- running under 6.0.x. It just won't communicate with the CDEV.
-
- The CDEV can be used to change these settings. This CDEV runs under 7.0 only;
- it won't show up under 6.0.x. Also, it checks to see if the INIT was installed
- at startup time. If not, then it puts up an alert saying that it won't run
- unless the INIT is installed. There's no real good reason for doing this
- (i.e., you should be able to change the preferences file for the next time you
- reboot). But it shows how you can do your own error reporting in a CDEV.
-
- The CDEV is based on the EditText CDEV sample. It's been modified slightly to
- communicate with the INIT. When it's brought up, you are presented with two
- edit text boxes. The first lets you set the number of times you beep. The
- second lets you set the interval in seconds. Nothing happens until you close
- the CDEV. When you do that, the CDEV uses the PPCToolbox to ask the INIT for a
- pointer to a public variables space. Once it has that pointer, it moves the
- new values into that space. The INIT then makes its decisions based on the new
- settings.
-
-
- About the files:
-
- The code for the CDEV is in CDEV.c. This is based on EditCDEV.c in DTS sample
- code #10. It's been augmented with some more error checking, the routines
- needed for PPCToolbox communication, and some number <-> string conversion
- routines.
-
- The code for the INIT is is INIT.c and INIT.a. Most of the meat, including the
- beeping and communication stuff, is in INIT.c. However, we use persistant
- global variables in the INIT (ala Technote #256), and have to keep around a
- reference to our globals during the time our SystemTask patch is not
- executing. To do this, we employ the services of a couple of routines in
- INIT.a. These routines, a_SetA5Ref and a_GetA5Ref, save and return our A5
- reference, which they store in a local DC.L. Also, the main entry point for
- our patch is in INIT.a. This entry point ("a_SystemTask") saves the registers,
- calls the C entry point ("c_SystemTask"), restores the registers, and then
- calls the original SystemTask in a way that doesn't consitute a tail patch.
-
- The installation code for the INIT is in INITInstall.a. This code checks to
- see if the shift key or mouse button are pressed. If so, it skips the install.
- If not, then it attempts to get memory in the system heap for the patch. If it
- can't get it, then it skips the install. If it does get it, it moves the patch
- into that new block of memory, and calls some more installation code in the C
- routines. If that installation code indicates some sort of error, the block of
- memory is de-allocated, and we blow out. Otherwise, the patch to SystemTask is
- made. If there were any errors, we use ShowINIT to show an unhappy icon.
- Otherwise, we show a happy icon.
-
- Because the CDEV and INIT exchange data back and forth, it's necessary for
- them to share some constants and data formats. These are defined in Common.h.
- The kind of stuff we consider common are message numbers and buffer formats.
- For instance, when we ask the INIT for the pointer to its common globals, we
- send it a message number "kGetCommonGlobalsPtr". This is defined in Common.h,
- so that we make sure that the value the INIT thinks is "kGetCommonGlobalsPtr"
- is the same value that the CDEV thinks it is. Similarly, the globals buffer
- format is defined in Commons.h. We also keep the name of the preferences file
- there, along with its file and creator type.
-
- Now that ResEdit is so damn cool, we don't have a Rez source file. All of our
- resources are stored in CDEV.rsrc, and were created with ResEdit. These
- resources get merged into our final file with a command in the makefile.
-
- Our INIT uses some global variables for convenience and so that we can have
- some persistant buffers for outstanding asynchronous PPCToolbox calls. To do
- this, we use the routines decribed in Technote #256, which are in the files
- SAGlobals.h and SAGlobals.c. However, we have modified them slightly for our
- own purposes. Some of the variables we will be using are things like parameter
- blocks for asynchronous PPCInform calls. Because the parameter block can't
- move out from under the PPCInform call, it needs to be in a non-relocatable
- block. Now, we could have just used the routines described in Technote #256
- and locked down our block of memory, but that's not a good idea. Our block of
- memory would need to be locked down all the time. Therefore, we want to it be
- in a part of the heap that can tolerate non-relocatable blocks. This means
- that it should go low in the heap. Without getting really tricky, we can't get
- a handle to go low in the heap. But there's no point; our globals will be
- locked ALL of the time, so we just allocate them with NewPtr. This has the
- added advantage making the Memory Manager put that block as low in the heap as
- it possibly can. So we modified the standard routines in SAGlobals.c to work
- with pointers and not handles.
-